{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "98dc533a-eafb-405f-81ec-0232f146ba2d",
   "metadata": {},
   "source": [
    "- https://zhuanlan.zhihu.com/p/1895815215712547750\n",
    "- https://usmanshahid.medium.com/llm-tool-calling-series-part-1-understanding-tool-calling-and-the-model-context-protocol-mcp-911a7c422fd8\n",
    "- https://modelcontextprotocol.io/quickstart/server"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "694d6f01-05eb-42b8-9b19-f04bf5d0895c",
   "metadata": {},
   "source": [
    "- gemini-cli：实现尽可能多地自主自动化地完成一些复杂且实用的任务\n",
    "    - 自动化地部署了网站，gcloud（sdk）\n",
    "    - chrome-mcp-stdio（chrome 浏览器），实现了在github上部署自己的学术主页\n",
    "        - https://github.com/hangwin/mcp-chrome\n",
    "        - https://github.com/academicpages/academicpages.github.io"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6eb1aa87-d0cd-4c51-9778-20584dd5d3a7",
   "metadata": {},
   "source": [
    "### 原理"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c07115d-d44c-4525-8300-780fe771461c",
   "metadata": {},
   "source": [
    "- 跨 mcp client（cline/cursor/gemini-cli/chatwise），跨 llm（deepseek，gemini，openai，Anthropic）\n",
    "    - 这个生态会越来越丰富，会有越来越多方便的 mcp server，很多服务会越来越 mcp sever 化\n",
    "- MCP 定义了 AI 应用（客户端）和外部工具（服务器）之间应该“说什么”（消息的格式和内容），而 STDIO 和 HTTP 则是实现“怎么说”（消息的传输通道）的方式\n",
    "-  http(sse) vs. stdio：\n",
    "    -  stdio: 本地进程间通信。\n",
    "    -  http(sse)：remote 网络通信\n",
    "        -  服务器发送事件 (Server-Sent Events, SSE)：SSE 是一种基于 HTTP 的协议，允许服务器通过一个持久的 HTTP 连接向客户端单向推送数据\n",
    "    -  启动方式\n",
    "        -  uvx（uv run）, npx, docker 等\n",
    "-  llm\n",
    "    -  `tools`（api 层面的） vs. system prompt\n",
    "        -  Cherry Studio 实际上是通过将 MCP Server 中提供的工具、响应结果，转换为 Function Call 的标准格式来和模型进行交互。\n",
    "        -  Cline 将 MCP Server 中提供的工具、响应结果转换未一套自己约定的输入、输出的标准数据格式，通过系统提示词来声明这种约定，再和模型进行交互。\n",
    "        -  这也解释了，为什么在 Cherry Studio 中只有一部分模型支持 MCP，前提是选择的模型需要支持 Function Call 的调用，并且在客户端进行了特殊适配；而 Cline 则使用的是系统提示词，所以所有模型都支持。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c09f542c-fd1e-45d9-8461-0442bd9c0cf0",
   "metadata": {},
   "source": [
    "### function calling"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc6e58ab-4218-432f-861a-beca8d151f1e",
   "metadata": {},
   "source": [
    "> LM 本身并不直接执行代码或调用 API，而是生成结构化的指令，由外部的应用程序或框架（即编排层，Orchestration，比如 mcp client）来解析和执行\n",
    "\n",
    "- 单次调用 => 多个工具同时调用（并行）\n",
    "    - https://platform.openai.com/docs/guides/function-calling?api-mode=chat#handling-function-calls\n",
    "    - `tool_calls` => execute 拿到 response => 追加到 messages 列表里（以 `tool` 的角色）`{\"role\": \"tool\", } `\n",
    "\n",
    "```json\n",
    "{\n",
    "  \"role\": \"assistant\",\n",
    "  \"content\": null,\n",
    "  \"tool_calls\": [\n",
    "    {\n",
    "      \"id\": \"call_abc123\",\n",
    "      \"type\": \"function\",\n",
    "      \"function\": {\n",
    "        \"name\": \"search_web\",\n",
    "        \"arguments\": \"{\\\"query\\\": \\\"LLM orchestration\\\"}\"\n",
    "      }\n",
    "    },\n",
    "    {\n",
    "      \"id\": \"call_def456\",\n",
    "      \"type\": \"function\",\n",
    "      \"function\": {\n",
    "        \"name\": \"get_weather\",\n",
    "        \"arguments\": \"{\\\"city\\\": \\\"San Francisco\\\"}\"\n",
    "      }\n",
    "    }\n",
    "  ]\n",
    "}\n",
    "\n",
    "[\n",
    "  {\n",
    "    \"role\": \"tool\",\n",
    "    \"tool_call_id\": \"call_abc123_weather\",\n",
    "    \"content\": \"{\\\"temperature\\\": 22, \\\"condition\\\": \\\"Sunny\\\"}\"\n",
    "  },\n",
    "  {\n",
    "    \"role\": \"tool\",\n",
    "    \"tool_call_id\": \"call_def456_search\",\n",
    "    \"content\": \"{\\\"summary\\\": \\\"LangChain released version X.Y.Z, introducing new features for agentic workflows and improved integration with vector databases...\\\"}\"\n",
    "  }\n",
    "]\n",
    "\n",
    "{\n",
    "  \"role\": \"assistant\",\n",
    "  \"content\": \"巴黎今天天气晴朗，气温为22摄氏度。关于 LangChain 的最新消息是，它最近发布了新版本 X.Y.Z，主要更新了智能体工作流和数据库集成等功能。\"\n",
    "}\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1670627c-7676-4330-a9bf-075dea9b6fec",
   "metadata": {},
   "source": [
    "### 拆解 sequentialthinking"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b132d44-12e6-4dd6-ae75-ecaede4ac842",
   "metadata": {},
   "source": [
    "> 规划一个5天的在北京的旅行计划，用 sequencialthinking 工具 \n",
    "\n",
    "- 分析这个工具，本地部署，修改源码/重新部署；\n",
    "- An advanced tool for **dynamic and reflective problem-solving** through **structured** thoughts.\n",
    "    - **branch** and **revise**\n",
    "        - 串行中的并行化\n",
    "    - \"required\": `[\"thought\", \"nextThoughtNeeded\", \"thoughtNumber\", \"totalThoughts\"]`\n",
    "        - 本地安装\n",
    "        - `docker build -f src/sequentialthinking/Dockerfile -t my-st-server .`\n",
    "        - `docker run --rm -i my-st-server`\n",
    "```\n",
    "\"sequential-thinking-docker\": {\n",
    "  \"command\": \"docker\",\n",
    "  \"args\": [\n",
    "    \"run\",\n",
    "    \"--rm\",\n",
    "    \"-i\",\n",
    "    \"my-st-server\"\n",
    "  ]\n",
    "}\n",
    "```\n",
    "- https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking\n",
    "- listTools, callTool\n",
    "  \n",
    "```ts\n",
    "server.setRequestHandler(ListToolsRequestSchema, async () => ({\n",
    "  tools: [SEQUENTIAL_THINKING_TOOL],\n",
    "}));\n",
    "\n",
    "server.setRequestHandler(CallToolRequestSchema, async (request) => {\n",
    "  if (request.params.name === \"sequentialthinking\") {\n",
    "    return thinkingServer.processThought(request.params.arguments);\n",
    "  }\n",
    "\n",
    "  return {\n",
    "    content: [{\n",
    "      type: \"text\",\n",
    "      text: `Unknown tool: ${request.params.name}`\n",
    "    }],\n",
    "    isError: true\n",
    "  };\n",
    "});\n",
    "```\n",
    "\n",
    "- thoughtHistory 的维护\n",
    "    - server 内部会维护 history，但向 mcp host 只返回 length，mcp host 中的 llm 自己在上下文中维护 history\n",
    "    - server：它的职责是成为一个有状态的工具。它就像一个有记忆的计算器，你不断给它输入，它在内部更新自己的状态。它只需要记住“思考”的上下文，并根据这个上下文处理新的“思考”。\n",
    "    - Host/Agent 的职责: 它的职责是决策。它根据 Server 返回的 nextThoughtNeeded标志来决定是否需要继续调用工具，进行下一步思考。它不需要知道历史记录的每一个细节，因为它（或者说它管理的 LLM）本身就是这些历史的创造者\n",
    "- 为什么需要这个工具？LLM 本身不就可以进行“链式思考” (Chain of Thought) 吗？\n",
    "    - 这是一个非常核心的问题。答案在于，这个工具为 LLM的思考过程提供了**外部的、结构化的、可交互的“脚手架”**，解决了原生“链式思考”的一些固有弊端。\n",
    "    - 原生链式思考 (CoT) 的局限\n",
    "        - 当你在提示 (Prompt) 中要求一个 LLM \"一步一步地思考\"时，它会在一次单一的、连续的生成中完成所有思考和回答。这个过程是：\n",
    "            - 整体的 (Monolithic): 思考和最终答案是一起生成的，无法将思考的每一步拆分成独立单元。\n",
    "            - 不可中断的 (Uninterruptible): 你无法在 LLM思考到第三步时暂停它，检查一下，或者给它一点新的信息，让它修正第三步然后继续。\n",
    "            - 难以观察和调试 (Poor Observability): 整个思考过程混在一大段文本里，对于开发者来说，很难以编程方式去解析和验证每一步的正确性。\n",
    "            - 修正成本高 (Costly to Correct): 如果 LLM 在第 2 步犯了错，但直到第 10 步才意识到，它通常需要重新生成整个思考链，或者在结尾附加一大段修正说明，这会使上下文变得混乱\n",
    "    - sequencialthinking\n",
    "        - 将思考过程“检查点化” (Checkpointing the Process)\n",
    "        - 实现真正的交互与修正 (Enabling True Interaction and Correction)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24fcad11-790f-41b7-916e-b2fa54f11e65",
   "metadata": {},
   "source": [
    "- 启动与工具发现：客户端（如一个聊天应用）启动后，向此服务器发起 ListToolsRequest 请求。服务器的 setRequestHandler 捕获该请求，并返回 [SEQUENTIAL_THINKING_TOOL]，将工具的“使用说明书”告知 LLM 。\n",
    "- 首次调用：用户提出问题。LLM 编排器将问题和工具定义一起发送给 LLM。LLM 根据 description 判断需要使用此工具，并生成第一次调用的 arguments，例如 {\"thought\": \"First, I need to understand the user's core requirement.\", \"thoughtNumber\": 1, \"totalThoughts\": 5, \"nextThoughtNeeded\": true}。\n",
    "- 服务器处理：服务器的 CallToolRequest 处理器被触发，调用 thinkingServer.processThought() 方法。该方法将第一个 ThoughtData 对象推入 thoughtHistory 数组，并在控制台打印出格式化的日志。\n",
    "- 循环信号：processThought 方法返回一个 JSON 字符串，如 {\"thoughtNumber\":1, \"nextThoughtNeeded\":true, ...}。\n",
    "- 迭代：LLM 编排器接收到这个响应，看到 nextThoughtNeeded: true，于是它将这个响应作为上下文，再次请求 LLM 生成下一步。LLM 看到第一步已被确认，于是生成对工具的第二次调用。\n",
    "- 结束：这个循环持续进行，直到 LLM 认为问题已经解决。届时，它会生成最后一次工具调用，并将 nextThoughtNeeded 设置为 false。编排器看到这个信号后，便会停止调用此工具，并要求 LLM 基于完整的 thoughtHistory（通过对话历史可知）生成最终的自然语言答案。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56b26f85-92db-44be-8d73-d397f41950c5",
   "metadata": {},
   "source": [
    "### uv 与 npx"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2c3f25a-8b92-4f4c-9a33-f5504c9ab36e",
   "metadata": {},
   "source": [
    "> 均非全局安装？\n",
    "\n",
    "- uv 是 python 的运行环境\n",
    "    -  `uvx` == `uv run tool`\n",
    "-  npx: node js 的运行环境\n",
    "    -  `npx excalidraw-mcp`\n",
    "    -  `npm install -g excalidraw-mcp`\n",
    "        -  globally install"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
